/*
 *  xmpp_connection.h
 *  wonderland-project
 *
 *  Created by Ben Nolan on 14/10/08.
 *  Copyright 2008 Nolan Consulting Limited. All rights reserved.
 *
 */

#pragma once

// Gross
#include "gloox/client.h"
#include "gloox/messagesessionhandler.h"
#include "gloox/messageeventhandler.h"
#include "gloox/messageeventfilter.h"
#include "gloox/chatstatehandler.h"
#include "gloox/chatstatefilter.h"
#include "gloox/connectionlistener.h"
#include "gloox/disco.h"
#include "gloox/message.h"
#include "gloox/gloox.h"
#include "gloox/presence.h"
#include "gloox/presencehandler.h"
#include "gloox/lastactivity.h"
#include "gloox/loghandler.h"
#include "gloox/logsink.h"
#include "gloox/connectiontcpclient.h"
#include "gloox/connectionsocks5proxy.h"
#include "gloox/connectionhttpproxy.h"
#include "gloox/messagehandler.h"
#include "gloox/registration.h"

#include <string>
#include <list>
#include <set>
#include <boost/signal.hpp>

namespace Wonderland{

  class XmppConnection : public gloox::ConnectionListener, gloox::MessageHandler, gloox::PresenceHandler, gloox::RegistrationHandler, gloox::LogHandler{
    public:
      XmppConnection();

      void connect();
      void createAccount();
      
      void poll();

      void send(std::string, std::string);

      std::string getNickname(){
        return nickname_;
      }
      
      void setNickname(std::string st){
        nickname_ = st;
      }
      
      std::string getServer(){
        return server_;
      }
      
      void setServer(std::string st){
        server_ = st;
      }
      
      std::string getPassword(){
        return "";
      }
      
      void setPassword(std::string pass){
        password_ = pass;
      }
      
      std::string getMessage(){
        std::string m;
        m = messages_.front();
        messages_.pop_front();
        return m;
      }
      
      bool hasMessages(){
        return messages_.size()>0;
      }
      
      bool isAuthenticated(){
        return authenticated_;
      }

      std::set<std::string> subscribers_;
 
      boost::signal<void ()> signal_connected;
      boost::signal<void (std::string)> signal_error;
      boost::signal<void ()> signal_disconnected;
      boost::signal<void (std::string, std::string)> signal_message;
      
    protected:
    
      // Connection handlers
      virtual void onConnect();
      virtual void onDisconnect( gloox::ConnectionError e );
      virtual bool onTLSConnect( const gloox::CertInfo& info );
      
      // Message handlers
      virtual void handleMessage(const gloox::Message& msg, gloox::MessageSession *session);
      virtual void handlePresence(const gloox::Presence &presence);

      // Registration handlers
      virtual void handleRegistrationFields( const gloox::JID& , int fields, std::string instructions );
      virtual void handleRegistrationResult( const gloox::JID& , gloox::RegistrationResult result );
      virtual void handleAlreadyRegistered( const gloox::JID& );
      virtual void handleDataForm(const gloox::JID&, const gloox::DataForm&);
      virtual void handleOOB(const gloox::JID&, const gloox::OOB&);

      // Logging
      virtual void handleLog( gloox::LogLevel level, gloox::LogArea area, const std::string& message );
      
    private:
      gloox::Client *j;
      gloox::ConnectionError ce_;
      gloox::Registration *registration_;
        
      std::list<std::string> messages_;
      
      int message_id_;

      gloox::JID jid_;
      std::string server_;
      std::string nickname_;
      std::string password_;
      
      bool connected_;
      bool authenticated_;
      bool registration_mode_;
  };

}